#ifndef SOCKS4A_TUNNEL_H
#define SOCKS4A_TUNNEL_H

#include "muduo/base/Logging.h"
#include "muduo/base/noncopyable.h"
#include "muduo/net/Callbacks.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"
#include "muduo/net/TcpClient.h"
#include "muduo/net/TcpServer.h"
using muduo::net::Buffer;
using muduo::net::EventLoop;
using muduo::net::InetAddress;
using muduo::net::TcpClient;
using muduo::net::TcpConnectionPtr;
using muduo::net::TcpServer;
/**
 * @brief 这是一个通道，相当于真正的proxy
 *
 */
class Tunnel : public std::enable_shared_from_this<Tunnel>, muduo::noncopyable {
 public:
  Tunnel(EventLoop* loop, const InetAddress& serverAddr, const TcpConnectionPtr& servercoon);
  void setup();
  void connect();
  void disconnect();
  ~Tunnel();

 private:
  void teardown();
  void onClientConnection(const muduo::net::TcpConnectionPtr& conn);
  void onClientMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf,
                       muduo::Timestamp);
  enum class ServerClient { kServer, kClient };
  void onHighWaterMark(ServerClient which, const muduo::net::TcpConnectionPtr& conn,
                       size_t bytesToSent);
  static void onHighWaterMarkWeak(const std::weak_ptr<Tunnel>& wkTunnel, ServerClient which,
                                  const muduo::net::TcpConnectionPtr& conn, size_t bytesToSent);
  // 低（空）水位回调函数
  void onWriteComplete(ServerClient which, const muduo::net::TcpConnectionPtr& conn);
  static void onWriteCompleteWeak(const std::weak_ptr<Tunnel>& wkTunnel, ServerClient which,
                                  const muduo::net::TcpConnectionPtr& conn);
  TcpClient client_;             // 客户端
  TcpConnectionPtr serverConn_;  // 与客户端的tcp连接 （自身作为server）
  TcpConnectionPtr clientConn_;  // 与服务器的连接（自身作为client）
};

#endif
